# 玩家角色控制脚本 - 包含移动、动画、背包、饥饿与生命值系统
extends CharacterBody2D
# 玩家基础属性与组件引用
# ===========================================
@export var health: float = 100.0          # 生命值（浮点数存储，显示时取整）
@export var hunger: float = 0.0            # 饥饿值（浮点数存储，显示时取整）
var speed: float = 300.0                   # 玩家移动速度（像素/秒）
@export var fireball_scene: PackedScene
# 受击系统
@export var hurt_sound: AudioStream        # 受伤音效资源
@export var shoot_sound: AudioStream			#发射火球音效
@export var heal_sound: AudioStream			
@export var eat_sound: AudioStream			
@export var collect_sound: AudioStream		
@export var invincibility_time: float = 1.0  # 无敌时间（秒）
var is_invincible: bool = false            # 是否处于无敌状态
var hurt_timer: Timer                      # 受击计时器
@onready var particle = $HurtParticles2D  #粒子效果

@onready var animated_sprite: AnimatedSprite2D = $AnimatedSprite2D  # 玩家动画精灵
@onready var health_label = $Camera2D/HealthLabel                   # 生命值UI标签
@onready var hunger_label = $Camera2D/HungerLabel                   # 饥饿值UI标签
@onready var backpack = $Camera2D/BackPack                         # 背包UI根节点
@export var inventory: Inventory                                     # 背包数据资源
var hunger_timer: Timer  # 饥饿计时器，每秒增加饥饿值
# ===========================================
# 初始化函数 - 游戏开始时调用一次
# ===========================================
func _ready() -> void:
	# 默认隐藏背包UI
	backpack.visible = false
	# 初始化状态显示
	update_stats()
	
	# 创建并配置饥饿计时器
	hunger_timer = Timer.new()
	add_child(hunger_timer)
	hunger_timer.wait_time = 1.0   # 每1秒触发一次
	hunger_timer.one_shot = false  # 循环触发
	hunger_timer.timeout.connect(_on_hunger_timer_timeout)
	hunger_timer.start()
	
	# 创建受击计时器（用于无敌时间）
	hurt_timer = Timer.new()
	add_child(hurt_timer)
	hurt_timer.wait_time = invincibility_time
	hurt_timer.one_shot = true
	hurt_timer.timeout.connect(_on_hurt_timer_timeout)
	
	# 将玩家加入分组，方便其他节点通过组名查找
	add_to_group("player")
# ===========================================
# 物理处理函数 - 每帧调用，处理移动、动画与背包开关
# ===========================================
func _physics_process(delta: float) -> void:
	# 获取方向输入（键盘 WASD/方向键）
	var direction := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	# 应用速度并移动
	velocity = direction * speed
	move_and_slide()
	# 根据移动方向更新动画
	update_animation(direction)
	# 背包开关控制（按背包键切换显示/隐藏）
	if Input.is_action_just_pressed("backpack"):
		backpack.visible = !backpack.visible
	if Input.is_action_just_pressed("fireball"):
		shoot_fireball()

# 火球发射函数 - 根据玩家当前动画方向发射火球
# 功能：实例化火球场景，根据玩家朝向设置火球飞行方向和生成位置
func shoot_fireball():
	# 实例化火球场景
	var fireball = fireball_scene.instantiate()
	# 根据玩家当前动画方向调整火球发射参数
	if animated_sprite.animation == "left":
		fireball.direction = Vector2.LEFT
	elif animated_sprite.animation == "right":
		fireball.direction = Vector2.RIGHT
	elif animated_sprite.animation == "up":
		fireball.direction = Vector2.UP	
	elif animated_sprite.animation == "down":
		fireball.direction = Vector2.DOWN
	# 设置火球的全局位置（玩家位置 + 偏移量）
	fireball.global_position = global_position
	# 将火球添加到当前游戏场景，使其可见并可交互
	get_tree().current_scene.add_child(fireball)
	if shoot_sound:
		var audio_player = AudioStreamPlayer2D.new()
		audio_player.stream = shoot_sound
		add_child(audio_player)
		audio_player.play()
		audio_player.finished.connect(audio_player.queue_free)

# ===========================================
# 动画更新函数 - 根据移动方向播放对应动画
# ===========================================
func update_animation(direction: Vector2) -> void:
	
	# 左右移动
	if direction.x != 0:
		animated_sprite.play("left" if direction.x < 0 else "right")
		
	# 上下移动
	elif direction.y != 0:
		animated_sprite.play("up" if direction.y < 0 else "down")
# ===========================================
# 收集物品函数 - 被可收集物品调用
# ===========================================
func collect(item) -> void:
	if collect_sound:
		var audio_player = AudioStreamPlayer2D.new()
		audio_player.stream = collect_sound
		add_child(audio_player)
		audio_player.play()
		audio_player.finished.connect(audio_player.queue_free)
	# 将物品插入背包数据
	inventory.insert(item)
	# 自动存档，防止物品丢失
	Global.save_game()
# ===========================================
# 饥饿计时器回调 - 每秒增加饥饿值
# ===========================================
func _on_hunger_timer_timeout() -> void:
	hunger += 1
	update_stats()
	# 饥饿值达到上限时死亡
	if hunger >= 100:
		die("饿死了")
# ===========================================
# 受伤函数 - 被敌人或陷阱调用
# ===========================================
func get_hurt() -> void:
	# 如果处于无敌状态，不受伤
	if is_invincible:
		return
	# 扣血并更新显示
	health -= 20
	update_stats()
	# 播放受伤音效
	if hurt_sound:
		var audio_player = AudioStreamPlayer2D.new()
		audio_player.stream = hurt_sound
		add_child(audio_player)
		audio_player.play()
		audio_player.finished.connect(audio_player.queue_free)
	# 开始受击动画和无敌时间
	start_hurt_animation()
	# 检查是否死亡
	if health <= 0:
		die("死了")
func heal():
	if heal_sound:
		var audio_player = AudioStreamPlayer2D.new()
		audio_player.stream = heal_sound
		add_child(audio_player)
		audio_player.play()
		audio_player.finished.connect(audio_player.queue_free)
	health += 20
	if health >= 100:
		health = 100
	update_stats()
func eat():
	if eat_sound:
		var audio_player = AudioStreamPlayer2D.new()
		audio_player.stream = eat_sound
		add_child(audio_player)
		audio_player.play()
		audio_player.finished.connect(audio_player.queue_free)

	hunger -= 5
	if hunger <= 0:
		hunger = 0
	update_stats()
# 受击动画 - 闪烁+震动+变色效果
# ===========================================
func start_hurt_animation() -> void:
	is_invincible = true
	hurt_timer.start()
	
	# 1. 红色闪烁效果
	var color_tween = create_tween()
	color_tween.set_loops(4)
	color_tween.tween_property(animated_sprite, "modulate", Color(1, 0.2, 0.2), 0.08)  # 变红
	color_tween.tween_property(animated_sprite, "modulate", Color(1, 1, 1), 0.08)   # 恢复
	color_tween.tween_callback(func(): animated_sprite.modulate = Color(1, 1, 1))
	
	# 2. 震动效果
	var original_pos = position
	var shake_tween = create_tween()
	shake_tween.set_loops(6)
	shake_tween.tween_property(self, "position", original_pos + Vector2(randf_range(-8, 8), randf_range(-8, 8)), 0.05)
	shake_tween.tween_property(self, "position", original_pos, 0.05)
	shake_tween.tween_callback(func(): position = original_pos)
	particle.restart()
# ===========================================
# 无敌时间结束回调
# ===========================================
func _on_hurt_timer_timeout() -> void:
	is_invincible = false
# ===========================================
# 死亡处理函数 - 统一处理各种死亡原因
# ===========================================
func die(reason: String) -> void:
	hunger_timer.stop()              # 停止饥饿计时
	Global.death_reason = reason       # 记录死亡原因
	get_tree().change_scene_to_file("res://scene/death_scene.tscn")  # 切换到死亡场景
# ===========================================
# 更新状态显示 - 刷新生命值与饥饿值UI
# ===========================================
func update_stats() -> void:
	health_label.text = "生命值：" + str(int(health))
	hunger_label.text = "饥饿值：" + str(int(hunger))

	
